/*
 * Copyright (c) jiucheng.org
 */
package org.jiucheng.template.grammar;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.jiucheng.template.util.Objs;

/**
 * 
 * @author jiucheng
 *
 */
public class For implements Grammar {
    public static final String FOR = "for";
    public static final String ROF = "rof";

    private String index;
    private String item;
    private String list;
    private List<Grammar> grammars = new ArrayList<Grammar>();

    public void add(Grammar grammar) {
        grammars.add(grammar);
    }

    public void addAll(List<Grammar> grammars) {
        this.grammars.addAll(grammars);
    }

    public For(String index, String item, String list) {
        this.index = index;
        this.item = item;
        this.list = list;
    }

    // for($item : $list)
    public For(String header) {
        // 解析FOR消息头
        header = header.substring(header.indexOf("(") + 1, header.lastIndexOf(")")).trim();
        String[] headers = header.split(":");
        if (headers.length == 2) {
            this.index = "i";
            this.item = headers[0].trim().substring(1);
            this.list = headers[1].trim().substring(1);
            return;
        }
        throw new RuntimeException("FOR Header Parser Error");
    }

    public void exec(Map<String, Object> context, StringBuilder sb) {
        Object objList = Objs.get(context, list);
        if (objList instanceof List) {
            List objs = (List) objList;
            for (int i = 0, len = objs.size(); i < len; i++) {
                context.put(item, objs.get(i));
                context.put(index, i + 1);
                for (Grammar grammar : grammars) {
                    grammar.exec(context, sb);
                }
            }
        } else if (objList instanceof Map) {
            Map map = (Map) objList;
            Set<Entry> entries = map.entrySet();
            int i = 1;
            Map<String, Object> obj;
            for (Entry entry : entries) {
                obj = new HashMap<String, Object>();
                obj.put("key", entry.getKey());
                obj.put("value", entry.getValue());
                context.put(item, obj);
                context.put(index, i);
                i++;
                for (Grammar grammar : grammars) {
                    grammar.exec(context, sb);
                }
            }
        }
    }
}
